package kotan.view.table;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JTable;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellEditor;

import kotan.KotanConstants;

class EntityTable extends JTable {

    /** logger */
    private static Logger logger = Logger.getLogger(EntityTable.class.getName());

    private static final long serialVersionUID = 1L;
    private final EntityTableModel tableModel;
    boolean nulllEdit = true;
    int lastEditRow;
    int lastEditColumn;

    EntityTable(EntityTableModel tableModel, DefaultTableColumnModel columnModel) {
        super(tableModel);
        this.tableModel = tableModel;
        setShowGrid(true);
        setGridColor(Color.GRAY);
        setAutoCreateColumnsFromModel(false);
        setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        // TODO F2 ?
//        putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
        setDefaultRenderer(Object.class, new EntityCellRenderer());
        setDefaultEditor(Boolean.class, new DefaultCellEditor(new JComboBox(
            new Boolean[] { Boolean.TRUE, Boolean.FALSE })));
        setDefaultEditor(Date.class, new DateCellEditor());
        //
        CellEditorListener selectListener = new CellEditorListener() {

            @Override
            public void editingStopped(ChangeEvent e) {
                if (logger.isLoggable(Level.FINE)) logger.fine("editingStopped:" + nulllEdit);
                changeSelection(lastEditRow, lastEditColumn, false, false);
            }

            @Override
            public void editingCanceled(ChangeEvent e) {
                if (logger.isLoggable(Level.FINE)) logger.fine("editingCanceled:" + nulllEdit);
                if (nulllEdit) EntityTable.this.tableModel.setValueAt(null, lastEditRow, lastEditColumn);
                changeSelection(lastEditRow, lastEditColumn, false, false);
            }
        };
        getDefaultEditor(Object.class).addCellEditorListener(selectListener);
        getDefaultEditor(Date.class).addCellEditorListener(selectListener);
        getDefaultEditor(Number.class).addCellEditorListener(selectListener);
        getDefaultEditor(Boolean.class).addCellEditorListener(selectListener);
        setSurrendersFocusOnKeystroke(true);
        setColumnModel(columnModel);
        getTableHeader().setColumnModel(columnModel);
        setModel(tableModel);
        setCellSelectionEnabled(true);
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        this.lastEditRow = row;
        this.lastEditColumn = column;
        boolean result = super.isCellEditable(row, column);
        if (logger.isLoggable(Level.FINE)) logger.fine("isCellEditable: " + result + "," + row + "," + column);
        return result;
    }

    @Override
    public TableCellEditor getCellEditor(int row, int column) {
        Object value = tableModel.getValueAt(convertRowIndexToModel(row), convertColumnIndexToModel(column));
        if (value != null) {
            TableCellEditor editor = super.getDefaultEditor(value.getClass());
            if (editor != null) return editor;
        }
        return super.getCellEditor(row, column);
    }

    @Override
    public String getToolTipText(MouseEvent evt) {
        int row = convertRowIndexToModel(rowAtPoint(evt.getPoint()));
        int col = convertColumnIndexToModel(columnAtPoint(evt.getPoint()));
        Object value = tableModel.get(row);
        if (value == null) return "null value";
        return String.format("<html>%s=%s<br/>[%s]</html>", tableModel.getColumnName(col), value.toString().replaceAll(
            "<",
            "&lt;"), value.getClass().getName());
    }

    class DateCellEditor extends AbstractCellEditor implements TableCellEditor {
        private static final long serialVersionUID = 1L;
        final JFormattedTextField dateField;

        DateCellEditor() {
            dateField = new JFormattedTextField(new SimpleDateFormat(KotanConstants.DEFAULT_DATE_FORMAT));
            dateField.setBorder(null);
            dateField.addPropertyChangeListener("value", new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    stopCellEditing();
                }
            });
        }

        @Override
        public Object getCellEditorValue() {
            return dateField.getValue();
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            dateField.setValue(value);
            return dateField;
        }
    }
}
